1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.google.common.base;
18
19 import com.google.common.annotations.GwtCompatible;
20 import com.google.common.annotations.GwtIncompatible;
21 import com.google.common.testing.GcFinalization;
22
23 import junit.framework.TestCase;
24
25 import java.lang.ref.WeakReference;
26 import java.util.Iterator;
27 import java.util.NoSuchElementException;
28
29
30
31
32
33
34 @GwtCompatible(emulated = true)
35
36 public class AbstractIteratorTest extends TestCase {
37
38 public void testDefaultBehaviorOfNextAndHasNext() {
39
40
41
42 Iterator<Integer> iter = new AbstractIterator<Integer>() {
43 private int rep;
44 @Override public Integer computeNext() {
45 switch (rep++) {
46 case 0:
47 return 0;
48 case 1:
49 return 1;
50 case 2:
51 return endOfData();
52 default:
53 fail("Should not have been invoked again");
54 return null;
55 }
56 }
57 };
58
59 assertTrue(iter.hasNext());
60 assertEquals(0, (int) iter.next());
61
62
63 assertTrue(iter.hasNext());
64 assertTrue(iter.hasNext());
65 assertTrue(iter.hasNext());
66 assertEquals(1, (int) iter.next());
67
68 assertFalse(iter.hasNext());
69
70
71 assertFalse(iter.hasNext());
72
73 try {
74 iter.next();
75 fail("no exception thrown");
76 } catch (NoSuchElementException expected) {
77 }
78 }
79
80 public void testSneakyThrow() throws Exception {
81 Iterator<Integer> iter = new AbstractIterator<Integer>() {
82 boolean haveBeenCalled;
83 @Override public Integer computeNext() {
84 if (haveBeenCalled) {
85 fail("Should not have been called again");
86 } else {
87 haveBeenCalled = true;
88 sneakyThrow(new SomeCheckedException());
89 }
90 return null;
91 }
92 };
93
94
95 try {
96 iter.hasNext();
97 fail("No exception thrown");
98 } catch (Exception e) {
99 if (!(e instanceof SomeCheckedException)) {
100 throw e;
101 }
102 }
103
104
105 try {
106 iter.hasNext();
107 fail("No exception thrown");
108 } catch (IllegalStateException expected) {
109 }
110 }
111
112 public void testException() {
113 final SomeUncheckedException exception = new SomeUncheckedException();
114 Iterator<Integer> iter = new AbstractIterator<Integer>() {
115 @Override public Integer computeNext() {
116 throw exception;
117 }
118 };
119
120
121 try {
122 iter.hasNext();
123 fail("No exception thrown");
124 } catch (SomeUncheckedException e) {
125 assertSame(exception, e);
126 }
127 }
128
129 public void testExceptionAfterEndOfData() {
130 Iterator<Integer> iter = new AbstractIterator<Integer>() {
131 @Override public Integer computeNext() {
132 endOfData();
133 throw new SomeUncheckedException();
134 }
135 };
136 try {
137 iter.hasNext();
138 fail("No exception thrown");
139 } catch (SomeUncheckedException expected) {
140 }
141 }
142
143 public void testCantRemove() {
144 Iterator<Integer> iter = new AbstractIterator<Integer>() {
145 boolean haveBeenCalled;
146 @Override public Integer computeNext() {
147 if (haveBeenCalled) {
148 endOfData();
149 }
150 haveBeenCalled = true;
151 return 0;
152 }
153 };
154
155 assertEquals(0, (int) iter.next());
156
157 try {
158 iter.remove();
159 fail("No exception thrown");
160 } catch (UnsupportedOperationException expected) {
161 }
162 }
163
164 @GwtIncompatible("weak references")
165 public void testFreesNextReference() {
166 Iterator<Object> itr = new AbstractIterator<Object>() {
167 @Override public Object computeNext() {
168 return new Object();
169 }
170 };
171 WeakReference<Object> ref = new WeakReference<Object>(itr.next());
172 GcFinalization.awaitClear(ref);
173 }
174
175 public void testReentrantHasNext() {
176 Iterator<Integer> iter = new AbstractIterator<Integer>() {
177 @Override protected Integer computeNext() {
178 hasNext();
179 return null;
180 }
181 };
182 try {
183 iter.hasNext();
184 fail();
185 } catch (IllegalStateException expected) {
186 }
187 }
188
189
190
191
192
193
194
195
196 private static void sneakyThrow(Throwable t) {
197 class SneakyThrower<T extends Throwable> {
198 @SuppressWarnings("unchecked")
199 void throwIt(Throwable t) throws T {
200 throw (T) t;
201 }
202 }
203 new SneakyThrower<Error>().throwIt(t);
204 }
205
206 private static class SomeCheckedException extends Exception {
207 }
208
209 private static class SomeUncheckedException extends RuntimeException {
210 }
211 }